<?php

class LsshellCommand extends CConsoleCommand
{
	
	public $runner;
	
	/**
	 * @return string the help information for the shell command
	 */
	public function getHelp()
	{
		return <<<EOD
USAGE
  yiic lsshell

DESCRIPTION
  This command allows you to interact with a Web application
  on the command line. It also provides tools to automatically
  generate new controllers, views and data models.

  It is recommended that you execute this command under
  the directory that contains the entry script file of
  the Web application.

EOD;
	}

	/**
	 * Execute the action.
	 * @param array command line parameters specific for this command
	 */
	public function run($args)
	{
		
		// reset context to run the web application
		restore_error_handler();
		restore_exception_handler();
		Yii::setApplication(null);
		Yii::setPathOfAlias('application',null);
		
		
		$url = parse_url(Config::Get('path.root.web').'/index.php');
		$cwd = Config::Get('path.root.server');
		chdir($cwd);
		
		$_SERVER['HTTP_HOST']=$url['host'];
		$_SERVER['SERVER_NAME']=$url['host'];
		$_SERVER['SERVER_PORT']=@$url['port']?$url['port']:80;
		$_SERVER['SCRIPT_NAME']=$url['path'];
		$_SERVER['REQUEST_URI']=$url['path'];
		$_SERVER['SCRIPT_FILENAME']=$cwd.DIRECTORY_SEPARATOR.'index.php';
		
		$app = Yii::E()->PluginYii_Yii_CreateApp('web', true);
		
		restore_error_handler();
		restore_exception_handler();

		if(!$args){
			$yiiVersion=Yii::getVersion();
			echo <<<EOD
Yii Interactive Tool v1.1 (based on Yii v{$yiiVersion})
Please type 'help' for help. Type 'exit' to quit.
EOD;
		}
		
		$this->runShell($args);
	}

	/**
	 * Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed.
	 * @param string prompt to echo out before waiting for user input
	 * @return mixed line read as a string, or false if input has been closed
	 */
	protected function readline($prompt)
	{
		if (extension_loaded('readline'))
		{
			$input = readline($prompt);
			readline_add_history($input);
			return $input;
		}
		else
		{
			echo $prompt;
			return fgets(STDIN);
		}
	}

	protected function runShell($args)
	{
		// disable E_NOTICE so that the shell is more friendly
		error_reporting(E_ALL ^ E_NOTICE);
		
		$engine = Yii::E();

		$_runner_=new CConsoleCommandRunner;
		$_runner_->addCommands(dirname(__FILE__).'/shell');
		
		$plugins = $engine->Plugin_GetActivePlugins();
		foreach($plugins as $plugin){
			$_runner_->addCommands(Yii::getPathOfAlias('application.plugins.'.$plugin.'.include.commands.shell'));
		}
		
		if(($_path_=@getenv('YIIC_SHELL_COMMAND_PATH'))!==false)
			$_runner_->addCommands($_path_);
		$_commands_=$_runner_->commands;
		$log=Yii::app()->log;
		
		$app = $engine->PluginYii_Yii_App();
		
		while(
			($_line_ = join(' ', $args))
			|| (($_line_=$this->readline("\n>> "))!==false)
		){
			$args = array();
			
			$_line_=trim($_line_);
			if($_line_==='exit')
				return;
			try
			{
				$_args_=preg_split('/[\s,]+/',rtrim($_line_,';'),-1,PREG_SPLIT_NO_EMPTY);
				if(isset($_args_[0]) && isset($_commands_[$_args_[0]]))
				{
					$_command_=$_runner_->createCommand($_args_[0]);
					array_shift($_args_);
					$_command_->run($_args_);
				}
				else
					echo eval($_line_.';');
			}
			catch(Exception $e)
			{
				if($e instanceof LsshellException)
					echo $e->getMessage();
				else
					echo $e;
			}
		}
	}
}

class LsshellException extends CException
{
}